/******************************************************************************
 * \brief	私有通信协议服务器端和客户端共用的函数接口
 * \details	与scp_server.c和scp_client.c中的接口一起实现通信模块的调用；
 *			SCP的含义是Self Communication Protocol，自己的通信协议；
 *			SCP协议处于传输层，传输层的数据包名为segment
 * \note	File format: UTF-8，中文编码：UTF-8
 * \author	将狼才鲸
 * \date	2023-03-23
 ******************************************************************************/

#ifndef _SCP_H_
#define _SCP_H_

/*********************************** 头文件 ***********************************/
#include "scp_devs.h"

/********************************** 结构定义 **********************************/
typedef void * scp_handle;	/* 通信协议句柄，等同于(scp_t *) */

/*
 * 协议数据结构：
 *		通信句柄scp_t中含有设备句柄scp_dev_t和发送队列wpkt_list，
 *		设备句柄中含有具体设备如scpdev_socket_t，
 *		发送队列中含有要发送的数据帧segment_t
 */

/**
 * \brief	通信协议句柄
 * \details	该结构体占用112~224字节，需要小于QBUF_GROUP_TMPBUF缓存的512字节
 */
typedef struct _scp {
	qbuf_t *qbuf;		/* 将自己通信结构体所在的缓存在此留一个指针入口 */
	scp_dev_t *pdev;	/* 设备结构体（会额外分配空间） */
	uint32_t CID;		/* 包信息中的连接id，是随机值，与segment_t中CID值相同 */
	uint32_t VCID[SCP_MAX_VCID_VALID];   /* connection id，发送包连接ID的缓存，用于判断对应的响应包 */
	uint32_t VSID[SCP_MAX_VSID_VALID];   /* segment id，最多的缓存个数 */
	/* 所有用户组的系列包发送队列（用于多发多收），不同的组有不同的操作权限，
	   发送队列里有要发送的数据段segment_t系列 */
	struct list_head wpkt_list[SECLVL_COUNT];
	segment_t *active_segment;	/* 当前已发送，正在等待响应的数据段指针，发送处理完则将其清空 */
} scp_t;

/********************************** 全局变量 **********************************/
extern scp_handle scp;	/* 默认通信句柄，全局变量，在别的模块中直接赋值 */

/********************************** 接口函数 **********************************/
/**
 * \brief	通信协议结构体指针是否有效
 * \return	有效返回真，无效返回假
 */
extern bool scp_valid(scp_t *pscp);

/**
 * \brief	通信协议句柄是否有效
 * \return	有效返回真，无效返回假
 */
extern bool scp_handle_valid(scp_handle hdl);

/**
 * \brief	建立一次通信连接
 * \details	可以调用多次，用不同的设备建立各自的连接
 * \param	hwaddr:	如果是进程间通信或多核通信，可以使用内存地址直接传递数据指针，
 *					省掉数据拷贝的时间，提高实时性
 * \param	type:	指定通信设备，如串口、网络、核间通信、进程间通信等，SCP_DEVTYPE_SOCKET...
 */
extern scp_handle scp_init(uint32_t hwaddr, uint8_t type);

/**
 * \brief	退出当前通信连接
 */
extern int scp_exit(scp_handle handle);

#endif /* _SCP_H_ */

/*********************************** 文件尾 ***********************************/
